import 'package:flutter/material.dart';
import 'package:logger/logger.dart';

class KeepAliveTest extends StatelessWidget {
  const KeepAliveTest({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Keep Alive Wrapper'),
      ),
      body: Center(
        child: ListView.builder(itemBuilder: (context, index) {
          return KeepAliveWrapper(
            // 为 true 后会缓存所有的列表项，列表项将不会销毁。
            // 为 false 时，列表项滑出预加载区域后将会别销毁。
            // 使用时一定要注意是否必要，因为对所有列表项都缓存的会导致更多的内存消耗
            keepAlive: false,
            child: HelloListItem(index: index),
          );
        }),
      ),
    );
  }
}

class HelloListItem extends StatefulWidget {
  final int index;

  const HelloListItem({Key? key, required this.index}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _HelloListItemState();
}

class _HelloListItemState extends State<HelloListItem> {
  final logger = Logger(printer: PrettyPrinter());

  @override
  Widget build(BuildContext context) {
    return ListTile(title: Text('${widget.index}'));
  }

  @override
  void dispose() {
    logger.i('dispose ${widget.index}');
    super.dispose();
  }
}

class KeepAliveWrapper extends StatefulWidget {
  const KeepAliveWrapper({Key? key, this.keepAlive = true, required this.child})
      : super(key: key);

  final bool keepAlive;

  final Widget child;

  @override
  State<StatefulWidget> createState() => _KeepAliveWrapperState();
}

class _KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return widget.child;
  }

  @override
  void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
    if (oldWidget.keepAlive != widget.keepAlive) {
      // keepAlive 状态需要更新，实现在 AutomaticKeepAliveClientMixin 中
      updateKeepAlive();
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  bool get wantKeepAlive => widget.keepAlive;
}
